///////////////////////////////////////////////////////////////*
// File: "CEmitter.cpp"
// Author: Ryan Burkevich (RB)
// Purpose: To contain all information for the CEmitter class.
///////////////////////////////////////////////////////////////

#include "CEmitter.h"
#include "../XML/tinyxml.h"
#include "../Wrappers/CSGD_TextureManager.h"

CEmitter::CEmitter()
{
	SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture("Particles/BS_Sparkle.png"));
	SetStartAlpha(255);
	SetStartRed(255);
	SetStartGreen(0);
	SetStartBlue(0);
	SetEndAlpha(255);
	SetEndRed(255);
	SetEndGreen(0);
	SetEndBlue(0);
	SetStartScale(1);
	SetEndScale(1);
	SetMinLife(0.5f);
	SetMaxLife(1.5f);
	SetPosX(195);
	SetPosY(300);
	SetMinVelX(-2.5f);
	SetMaxVelX(2.5f);
	SetMinVelY(-2.5f);
	SetMaxVelY(-2.5f);
	SetNumPart(60);
	SetEmitWidth(1);
	SetEmitHeight(1);
	SetPlaying(false);
	SetPlayTimer(.5f);
}

CEmitter::~CEmitter()
{

}

void CEmitter::InitParticles()
{
	m_vParticles.clear();

	for(int i = 0; i < GetNumPart(); i++)
	{
		tParticle Particle;
		
		Particle.nID = i;
		Particle.fScale = GetStartScale();
		Particle.nCurrentAColor = GetStartAlpha();
		Particle.nCurrentRColor = GetStartRed();
		Particle.nCurrentGColor = GetStartGreen();
		Particle.nCurrentBColor = GetStartBlue();

		Particle.fAge = RAND_FLOAT(0.0f, 1.0f) * (GetMaxLife() - GetMinLife()) + GetMinLife(); 

		Particle.bAlive = true;
		Particle.tPos.fX = RAND_FLOAT(GetPosX() - (GetEmitWidth() / 2), GetPosX() + (GetEmitHeight() / 2));
		Particle.tPos.fY = RAND_FLOAT(GetPosY() - (GetEmitWidth() / 2), GetPosY() + (GetEmitHeight() / 2));
		Particle.tVel.fX = RAND_FLOAT(0.0f, 1.0f) * (GetMaxVelX() - GetMinVelX()) + GetMinVelX();
		Particle.tVel.fY = RAND_FLOAT(0.0f, 1.0f) * (GetMaxVelY() - GetMinVelY()) + GetMinVelY();

		m_vParticles.push_back(Particle);
	}
}

void CEmitter::UpdateParticles(float fElapsedTime)
{
	if(GetPlaying())
	{
		for(unsigned int i = 0; i < m_vParticles.size(); i ++)
		{
			m_vParticles[i].tPos.fX += m_vParticles[i].tVel.fX;
			m_vParticles[i].tPos.fY += m_vParticles[i].tVel.fY;
			m_vParticles[i].nCurrentAColor = (int)(((GetMaxLife() - m_vParticles[i].fAge) / GetMaxLife()) * ( GetEndAlpha() - GetStartAlpha()) + GetStartAlpha());
			m_vParticles[i].nCurrentRColor = (int)(((GetMaxLife() - m_vParticles[i].fAge) / GetMaxLife()) * ( GetEndRed() - GetStartRed()) + GetStartRed());
			m_vParticles[i].nCurrentGColor = (int)(((GetMaxLife() - m_vParticles[i].fAge) / GetMaxLife()) * ( GetEndGreen() - GetStartGreen()) + GetStartGreen());
			m_vParticles[i].nCurrentBColor = (int)(((GetMaxLife() - m_vParticles[i].fAge) / GetMaxLife()) * ( GetEndBlue() - GetStartBlue()) + GetStartBlue());
			m_vParticles[i].fScale = ((GetMaxLife() - m_vParticles[i].fAge) / GetMaxLife()) * (GetEndScale() - GetStartScale()) + GetStartScale();

			m_vParticles[i].fAge -= fElapsedTime;
			if(m_vParticles[i].fAge <= 0.0f)
			{
				m_vParticles[i].nID = i;
				m_vParticles[i].fScale = GetStartScale();
				m_vParticles[i].nCurrentAColor = GetStartAlpha();
				m_vParticles[i].nCurrentRColor = GetStartRed();
				m_vParticles[i].nCurrentGColor = GetStartGreen();
				m_vParticles[i].nCurrentBColor = GetStartBlue();
				m_vParticles[i].fAge = RAND_FLOAT(0.0f, 1.0f) * (GetMaxLife() - GetMinLife()) + GetMinLife();
				m_vParticles[i].bAlive = true;
				m_vParticles[i].tPos.fX = RAND_FLOAT(GetPosX() - (GetEmitWidth() / 2), GetPosX() + (GetEmitHeight() / 2));
				m_vParticles[i].tPos.fY = RAND_FLOAT(GetPosY() - (GetEmitWidth() / 2), GetPosY() + (GetEmitHeight() / 2));
				m_vParticles[i].tVel.fX = RAND_FLOAT(0.0f, 1.0f) * (GetMaxVelX() - GetMinVelX()) + GetMinVelX();
				m_vParticles[i].tVel.fY = RAND_FLOAT(0.0f, 1.0f) * (GetMaxVelY() - GetMinVelY()) + GetMinVelY();
			}
		}
		SetPlayTimer(GetPlayTimer() - fElapsedTime);
	}

	if(GetPlayTimer() <= 0)
	{
		SetPlaying(false);
		SetPlayTimer(.5f);
		m_vParticles.clear();
	}	
}

void CEmitter::RenderParticles()
{
	CSGD_TextureManager* pTM = CSGD_TextureManager::GetInstance();
	CSGD_Direct3D* pD3D = CSGD_Direct3D::GetInstance();

	DWORD dwTempSource = 0, dwTempDest = 0;

	pD3D->GetDirect3DDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
	pD3D->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, dwTempSource);
	pD3D->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, dwTempDest);
	pD3D->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, m_nSourceBlend);
	pD3D->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, m_nDestBlend);

	if(GetPlaying())
	{
		for(int i = 0; i < GetNumPart(); i++)
		{
			pTM->Draw(GetImageID(), (int)m_vParticles[i].tPos.fX, (int)m_vParticles[i].tPos.fY, m_vParticles[i].fScale, m_vParticles[i].fScale,
				0, 0, 0, 0, D3DCOLOR_ARGB(m_vParticles[i].nCurrentAColor, m_vParticles[i].nCurrentRColor, m_vParticles[i].nCurrentGColor, m_vParticles[i].nCurrentBColor));
		}
	}
	pD3D->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, dwTempSource);
	pD3D->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, dwTempDest);
	pD3D->GetDirect3DDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
}

bool CEmitter::Load(const char* szFileName)
{
	TiXmlDocument xmlDoc;
	
	if(!xmlDoc.LoadFile(szFileName))
		return false;

	int		nXmlIntData = 0;
	double  dXmlDoubleData = 0;

	TiXmlElement* pRoot = xmlDoc.RootElement();
	
	pRoot->Attribute("NumParticles", &nXmlIntData);
	SetNumPart(nXmlIntData);
	pRoot->Attribute("StartAlpha", &nXmlIntData);
	SetStartAlpha(nXmlIntData);
	pRoot->Attribute("StartRed", &nXmlIntData);
	SetStartRed(nXmlIntData);
	pRoot->Attribute("StartGreen", &nXmlIntData);
	SetStartGreen(nXmlIntData);
	pRoot->Attribute("StartBlue", &nXmlIntData);
	SetStartBlue(nXmlIntData);

	pRoot->Attribute("EndAlpha", &nXmlIntData);
	SetEndAlpha(nXmlIntData);
	pRoot->Attribute("EndRed", &nXmlIntData);
	SetEndRed(nXmlIntData);
	pRoot->Attribute("EndGreen", &nXmlIntData);
	SetEndGreen(nXmlIntData);
	pRoot->Attribute("EndBlue", &nXmlIntData);
	SetEndBlue(nXmlIntData);

	pRoot->Attribute("StartScale", &dXmlDoubleData);
	SetStartScale((float)dXmlDoubleData);
	pRoot->Attribute("EndScale", &dXmlDoubleData);
	SetEndScale((float)dXmlDoubleData);

	pRoot->Attribute("MinLife", &dXmlDoubleData);
	SetMinLife((float)dXmlDoubleData);
	pRoot->Attribute("MaxLife", &dXmlDoubleData);
	SetMaxLife((float)dXmlDoubleData);

	pRoot->Attribute("XPos", &dXmlDoubleData);
	SetPosX((float)dXmlDoubleData);
	pRoot->Attribute("YPos", &dXmlDoubleData);
	SetPosY((float)dXmlDoubleData);

	pRoot->Attribute("MinXVel", &dXmlDoubleData);
	SetMinVelX((float)dXmlDoubleData);
	pRoot->Attribute("MaxXVel", &dXmlDoubleData);
	SetMaxVelX((float)dXmlDoubleData);
	
	pRoot->Attribute("MinYVel", &dXmlDoubleData);
	SetMinVelY((float)dXmlDoubleData);
	pRoot->Attribute("MaxYVel", &dXmlDoubleData);
	SetMaxVelY((float)dXmlDoubleData);

	pRoot->Attribute("Width", &dXmlDoubleData);
	SetEmitWidth((float)dXmlDoubleData);
	pRoot->Attribute("Height", &dXmlDoubleData);
	SetEmitHeight((float)dXmlDoubleData);

	pRoot->Attribute("SourceBlend", &nXmlIntData);
	SetSourceBlend(nXmlIntData);
	pRoot->Attribute("DestBlend", &nXmlIntData);
	SetDestBlend(nXmlIntData);

	SetFileName(pRoot->Attribute("FileName"));
	SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture((char*)GetFileName().c_str()));

	InitParticles();

	return true;
}